home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
Tutorial
/
Cookbook
/
41.PieChart
/
PieView.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
8KB
|
361 lines
/* Generated by Interface Builder */
#import "PieView.h"
#import "stdio.h"
#import <dpsclient/wraps.h>
#import <appkit/Font.h>
#import <appkit/Application.h>
#import <appkit/Pasteboard.h>
#import <appkit/Cell.h>
#import <appkit/Matrix.h>
#import <appkit/Slider.h>
#import <appkit/OpenPanel.h>
#import <appkit/Panel.h>
#import <appkit/Control.h>
#import <appkit/Form.h>
#import <strings.h>
#import "slice.h"
#import "math.h"
@implementation PieView
static char logString[10000];
+newFrame:(const NXRect *)tF
{
int i;
char buf[4];
int used;
FILE *fd;
// we are using the Appkit "newFrame" plus our own additions
self = [super newFrame:tF];
numDrawSegments = 2;
gray[0] = .333;
gray[1] = .666;
strcpy(displayLabel[0],"/");
strcpy(displayLabel[1],"free");
/* kludge becuase there is no UNIX documentation on the
* system call to get disk free space
*/
system("df / | tail -1 | awk '{print $5}' >/tmp/root_space_used");
fd = (FILE *) openFileReadOnly("/tmp/root_space_used");
fgets(buf, 4, fd);
sscanf(buf, "%d", &used);
fclose(fd);
displayValue[0] = (float) used;
displayValue[1] = (float) (100 - used);
norm[0] = displayValue[0]*3.6;
norm[1] = displayValue[1]*3.6;
myFont = [Font newFont:"Helvetica"
size:10.0
style:0
matrix:NX_IDENTITYMATRIX];
pieSize = 200.0;
pieFontSize = 10.0;
openReq = [OpenPanel new];
c_x = bounds.size.width/2.0;
c_y = bounds.size.height/2.0;
[self translate:c_x :c_y];
return self;
}
- showError: (char *)errorMessage
{
NXRunAlertPanel("Pie_Matrix", errorMessage,"OK",NULL,NULL);
}
// --------------- methods that respond to user actions start here --------------
- getValue:sender
{
int i;
i = [sender selectedRow];
displayValue[i] = [sender floatValue];
// printf("Row = %d Value = %f\n", i, displayValue[i]);
[self display];
return self;
}
- getLabel:sender
{
int i;
i = [sender selectedRow];
strcpy(displayLabel[i],[sender stringValue]);
// printf("Row = %d String = %s\n", i, displayLabel[i]);
[self display];
return self;
}
- getnSlices:sender
{
numDrawSegments = [sender intValue];
[self display];
return self;
}
- getPieSize:sender
{
pieSize = [sender floatValue];
[pieSizeText setFloatValue:pieSize];
[self display];
return self;
}
- getPieFontSize:sender
{
pieFontSize = [sender floatValue];
myFont = [Font newFont:"Helvetica"
size:pieFontSize
style:0
matrix:NX_IDENTITYMATRIX];
[pieFontText setFloatValue:pieFontSize];
[self display];
return self;
}
- printDisplayList:sender
{
int i;
printf("Display List:\n");
for (i=0; i<numDrawSegments; i++) {
printf("%7.0f %s\n", displayValue[i], displayLabel[i]);
}
return self;
}
- printTree:sender
{
printf("Tree Structure:\n");
treeprint(root, 0);
return self;
}
- openRequest:sender
{
const char *fileName;
const char *const types[4] = {NULL,NULL};
int ok;
if ([openReq runModalForTypes:types] && (fileName =[openReq filename])) {
[self openFile:fileName];
}
else
[self showError:"No file chosen or could not open file"];
return self;
}
- copy:sender {
id pb = [NXApp pasteboard]; /* global Pasteboard object */
NXStream *st; /* stream to collect data in */
char *data; /* actual data buffer */
int length; /* length of data */
int maxLength; /* (not used here) */
// To see how to use the pasteboard see page 10-33 of
// the SysRefMan
// declare that we will supply a single type of data: PostScript
[pb declareTypes:&NXPostScriptPboard num:1 owner:self];
/* get a stream which writes to memory */
st = NXOpenMemory( NULL, 0, NX_WRITEONLY );
/* write PostScript code for this view into the stream */
[self copyPSCodeInside:NULL to:st];
/* get actual data buffer from stream */
NXGetMemoryBuffer( st, &data, &length, &maxLength );
/* write PostScript data to pasteboard */
[pb writeType:NXPostScriptPboard data:data length:length];
/* deallocate stream, including its buffer */
NXCloseMemory( st, NX_FREEBUFFER );
return self;
}
// ---------------- Outlets start here ------------------
- setXForm:anObject
{
xForm = anObject;
return self;
}
- setYForm:anObject
{
yForm = anObject;
return self;
}
- setPieSizeText:anObject
{
pieSizeText = anObject;
return self;
}
- setPieFontText:anObject
{
pieFontText = anObject;
return self;
}
-(int) openFile:(const char *)fileName
{
int i=0;
char buf[MAX_CHARS_PER_LINE], tmpStr[MAX_CHARS_PER_LINE];
FILE *input_fp;
float total=0.0;
int ret=0;
if (( input_fp = fopen(fileName, "r") ) == NULL ) {
[self showError:"Could not open file"];
fprintf(stderr, "File: %s Could not be opened.\n", fileName);
return NO;
}
/* initialize root value of tree */
root = createNode("/", 0);
root->stop = NO;
while (fgets(buf, MAX_CHARS_PER_LINE, input_fp) != NULL) {
if (i >= MAX_LINES) {
printf("Too many lines\n");
break;
}
if (strlen(buf) == 1) {
printf("Blank Line\n");
break;
}
ret = sscanf(buf, "%f %s", &displayValue[i], displayLabel[i]);
if (ret == 1) {
root->word = strdup("/");
root->value = displayValue[i];
} else {
/* printf("In: %f %s\n", displayValue[i], displayLabel[i]); */
addtree(root, displayLabel[i], displayValue[i]);
i++;
}
}
numDataLines = i;
printf("%d data points read\n\n", numDataLines);
fclose(input_fp);
numDrawSegments = buildDisplayList(root, 0, 0, "/");
normalize(displayValue, norm, 360, numDrawSegments);
for (i=0; i<numDrawSegments; i++) {
angle[i] = norm[i] + total;
total += norm[i];
}
[self display];
return YES;
}
/* make this view accept first responder so it will understand copy */
-(BOOL)acceptsFirstResponder
{
return (YES);
}
-resignFirstResponder
{
return self;
}
- drawSelf:(NXRect*)r :(int)c
{
int i;
float total = 0.0;
c_x = bounds.size.width/2.0 + bounds.origin.x;
c_y = bounds.size.height/2.0 + bounds.origin.y;
[self translate:c_x :c_y];
[myFont set];
PSsetgray(1.0);
NXRectFill(&bounds);
PSsetgray(0.0);
for (i=0; i<numDrawSegments; i++)
{
drawSlice(gray[i], pieSize, total, total+norm[i], pieFontSize, displayLabel[i]);
total = total + norm[i];
}
return self;
}
// mouse handeling starts here
static char logString[10000];
/* add a string to the log and have text updated */
static void addStringLog(target, string)
char *string;
id target;
{
strcat(logString, string);
[target setStringValue:logString];
}
/* add an event to the log text */
static void addEventLog(target, string, x, y, type)
char *string;
id target;
float x,y;
int type;
{
static char tmpString[100];
strcat(logString, string);
if (type == 1) strcat(logString, " DOWN ");
else if (type == 2) strcat(logString, " UP ");
else if (type == 6) strcat(logString, " DRAG ");
else {
sprintf(tmpString, " type=%d ", type);
strcat(logString, tmpString);
}
sprintf(tmpString, "at x=%3.0f y=%3.0f\n", x, y);
strcat(logString, tmpString);
[target setStringValue:logString];
}
// from chapter 7 page 61
- mouseDown:(NXEvent *)thisEvent
{
register int i=0;
NXPoint Loc;
float mouseAngle, total=0.0;
Treeptr p;
// printf("click type = %d\n", data.mouse.click);
Loc = thisEvent->location;
[self convertPoint:&Loc fromView:nil];
mouseAngle = 180.0/3.14158*atan(Loc.y/Loc.x);
if (Loc.x < 0.0)
mouseAngle = mouseAngle + 180.0;
if ((Loc.x > 0.0) && (Loc.y < 0.0))
mouseAngle = mouseAngle + 360.0;
while (mouseAngle > angle[i])
i++;
p = locateInTree(root, displayLabel[i]);
numDrawSegments = buildDisplayList(root, 0, 0, "/");
normalize(displayValue, norm, 360, numDrawSegments);
for (i=0; i<numDrawSegments; i++) {
angle[i] = norm[i] + total;
total += norm[i];
}
[self display];
return(self);
}
@end